package com.common.sevice.impl;

import com.common.constanct.CommonUtils;
import com.common.entity.SystemApplicationEntity;
import com.common.model.SystemApplicationModel;
import com.common.model.SystemApplicationServiceModel;
import com.common.model.SystemApplicationWebModel;
import com.common.mysql.Where;
import com.common.service.impl.SimpleServiceImpl;
import com.common.service.impl.TreeSimpleServiceImpl;
import com.common.sevice.SystemApplicationModelService;
import com.common.sevice.SystemApplicationService;
import com.common.sevice.SystemApplicationWebService;
import com.common.sevice.SystemImageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SystemApplicationServiceImpl extends SimpleServiceImpl<String, SystemApplicationModel, SystemApplicationEntity> implements SystemApplicationService {

    @Autowired
    private SystemApplicationModelServiceImpl modelService;

    @Autowired
    @Lazy
    private SystemImageServiceImpl systemImageService;

    @Autowired
    private SystemApplicationWebService webService;

    @Override
    public void addTemplate(SystemApplicationModel model) {
        String appId = model.getId();
        List<SystemApplicationServiceModel> modelTemplateList = modelService.search(Where.build().field("app_id").equal("000000000000000000000000000000")
                .and().field("del_flag").equal(0));
        List<SystemApplicationServiceModel> topServiceModelList = modelTemplateList.stream()
                .filter(m -> ObjectUtils.isEmpty(m.getParentId()))
                .map(m->{
                    m.setAppId(appId);
                    return m;
                }).collect(Collectors.toList());
        Map<String, List<SystemApplicationServiceModel>> childrenModelMap = modelTemplateList.stream()
                .filter(m -> !ObjectUtils.isEmpty(m.getParentId()))
                .map(m->{
                    m.setAppId(appId);
                    return m;
                }).collect(Collectors.groupingBy(SystemApplicationServiceModel::getParentId));
        List<SystemApplicationServiceModel> addList = new LinkedList<>();
        dealWithServiceModelList(topServiceModelList, childrenModelMap, addList, null);
        addList.stream().forEach(modelService::add);
        List<SystemApplicationWebModel> webTemplateList = webService.search(Where.build().field("app_id").equal("000000000000000000000000000000")
                .and().field("del_flag").equal(0));
        List<SystemApplicationWebModel> topServiceWebList = webTemplateList.stream()
                .filter(m -> ObjectUtils.isEmpty(m.getParentId()))
                .map(m->{
                    m.setAppId(appId);
                    return m;
                }).collect(Collectors.toList());
        Map<String, List<SystemApplicationWebModel>> childrenWebModelMap = webTemplateList.stream()
                .filter(m -> !ObjectUtils.isEmpty(m.getParentId()))
                .map(m->{
                    m.setAppId(appId);
                    return m;
                }).collect(Collectors.groupingBy(SystemApplicationWebModel::getParentId));
        List<SystemApplicationWebModel> addWebList = new LinkedList<>();
        dealWithWebModelList(topServiceWebList, childrenWebModelMap, addWebList, null);
        addWebList.stream().forEach(webService::add);
    }

    @Override
    public void deleteChildren(SystemApplicationModel model) {
        String id = model.getId();
        List<SystemApplicationServiceModel> modelList = modelService.search(Where.build().field("app_id").equal(id));
        if (!CollectionUtils.isEmpty(modelList)){
            for (SystemApplicationServiceModel serviceModel : modelList) {
                modelService.delete(serviceModel.getId());
            }
        }
        List<SystemApplicationWebModel> webModelList = webService.search(Where.build().field("app_id").equal(id));
        if (!CollectionUtils.isEmpty(webModelList)){
            for (SystemApplicationWebModel webModel : webModelList) {
                modelService.delete(webModel.getId());
            }
        }
    }

    @Override
    public String generateSql(String appId) {
        StringBuffer result = new StringBuffer();
        result.append("CREATE TABLE `system_application` (\n" +
                "  `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" +
                "  `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '应用名称',\n" +
                "  `user_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '所有人名称',\n" +
                "  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '0' COMMENT '删除标识（0 未删除 1 已删除）',\n" +
                "  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n" +
                "  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n" +
                "  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `background_url` varchar(255) DEFAULT NULL COMMENT '背景图片',\n" +
                "  `enter_app_before_login` varchar(1) DEFAULT '1',\n" +
                "  PRIMARY KEY (`id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC;");

        result.append("CREATE TABLE `system_application_service` (\n" +
                "  `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" +
                "  `parent_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父级id',\n" +
                "  `app_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '应用id',\n" +
                "  `data` json DEFAULT NULL,\n" +
                "  `type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '类型 1:文件夹 2:api接口 3:model类型',\n" +
                "  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '接口路径',\n" +
                "  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n" +
                "  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n" +
                "  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '0' COMMENT '删除标识（0 未删除 1已删除）',\n" +
                "  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `sort` int DEFAULT '0' COMMENT '排序',\n" +
                "  `extra` json DEFAULT NULL,\n" +
                "  PRIMARY KEY (`id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC;");

        result.append("CREATE TABLE `system_application_web` (\n" +
                "  `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" +
                "  `parent_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父级id',\n" +
                "  `app_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '应用id',\n" +
                "  `data` json DEFAULT NULL COMMENT '页面资源',\n" +
                "  `type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '页面类型（1:文件夹 2:页面 3:自定义菜单）',\n" +
                "  `label` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单名称(中文)',\n" +
                "  `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单名称（英文）',\n" +
                "  `icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '菜单图标',\n" +
                "  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n" +
                "  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n" +
                "  `del_flag` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '0' COMMENT '删除标识（0:未删除 1:已删除）',\n" +
                "  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `sort` int DEFAULT '0' COMMENT '排序',\n" +
                "  `extra` json DEFAULT NULL,\n" +
                "  PRIMARY KEY (`id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC;");
        result.append("CREATE TABLE `system_user` (\n" +
                "  `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" +
                "  `account` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  `create_time` datetime DEFAULT NULL,\n" +
                "  `update_time` datetime DEFAULT NULL,\n" +
                "  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '0',\n" +
                "  `remarks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,\n" +
                "  PRIMARY KEY (`id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC;");
        String businessTableSql = systemImageService.createBusinessTableSql(appId);
        if (StringUtils.hasText(businessTableSql)){
            result.append(businessTableSql);
        }
        String ddmSql = systemImageService.createDdmSql(appId);
        if (StringUtils.hasText(ddmSql)){
            result.append(ddmSql);
        }

        return result.toString();
    }

    private void dealWithServiceModelList(List<SystemApplicationServiceModel> modelList, Map<String, List<SystemApplicationServiceModel>> childrenModelMap, List<SystemApplicationServiceModel> addList, String parentId) {
        for (SystemApplicationServiceModel model : modelList) {
            String oldId = model.getId();
            String newId = CommonUtils.get32UUID();
            model.setId(newId);
            model.setParentId(parentId);
            addList.add(model);
            if (childrenModelMap.containsKey(oldId)) {
                dealWithServiceModelList(childrenModelMap.get(oldId), childrenModelMap, addList, newId);
            }
        }
    }

    private void dealWithWebModelList(List<SystemApplicationWebModel> modelList, Map<String, List<SystemApplicationWebModel>> childrenModelMap, List<SystemApplicationWebModel> addList, String parentId) {
        for (SystemApplicationWebModel model : modelList) {
            String oldId = model.getId();
            String newId = CommonUtils.get32UUID();
            model.setId(newId);
            model.setParentId(parentId);
            addList.add(model);
            if (childrenModelMap.containsKey(oldId)) {
                dealWithWebModelList(childrenModelMap.get(oldId), childrenModelMap, addList, newId);
            }
        }
    }
}
